<template>
    <div class="create-edit-modal-wrapper">
        <el-dialog :model-value="props.value" :title="dialog.title" :width="dialog.width" destroy-on-close>
            <el-form ref="ruleFormRef" :model="formData" :rules="ruleForm" label-width="120px">
                <div class="form-item-box-one">
                    <div>
                        <el-form-item label="模型名称" prop="displayName">
                            <el-input
                                v-model="formData.displayName"
                                @input="value => (formData.displayName = value.trim())"
                                placeholder="请输入模型名称"
                                :disabled="isEdit()"
                                maxlength="50"
                            />
                        </el-form-item>
                        <el-form-item label="标识符" prop="objectName">
                            <el-input
                                v-model="formData.objectName"
                                @input="value => (formData.objectName = value.trim())"
                                placeholder="请输入标识符"
                                :disabled="isEdit()"
                                maxlength="50"
                            />
                        </el-form-item>
                        <el-form-item label="显示顺序">
                            <el-input-number
                                v-model="formData.showOrder"
                                :precision="0"
                                :min="1"
                                style="width: 100%"
                                align="left"
                                controls-position="right"
                                placeholder="请输入显示顺序"
                            />
                        </el-form-item>
                        <el-form-item
                            label="父模型"
                            prop="parentObjectName"
                            v-if="formData.modifierType === 'EXTENDED'"
                        >
                            <el-select
                                v-model="formData.parentObjectName"
                                placeholder="请选择父模型"
                                filterable
                                @change="parentObjectNameChange"
                                :disabled="isEdit()"
                            >
                                <el-option
                                    v-for="item in parentModelList"
                                    :label="item.displayName"
                                    :key="item.objectName"
                                    :value="item.objectName"
                                />
                            </el-select>
                        </el-form-item>
                    </div>
                    <div>
                        <el-form-item label="图片">
                            <IconSelect v-model="formData.icon" />
                        </el-form-item>
                        <el-form-item label="模型性质" prop="modifierType">
                            <el-select
                                v-model="formData.modifierType"
                                @change="modifierTypeChange"
                                :disabled="isEdit()"
                            >
                                <el-option
                                    v-for="(value, key) in modifierType"
                                    :label="value"
                                    :key="key"
                                    :value="key"
                                />
                            </el-select>
                        </el-form-item>
                    </div>
                </div>
                <div class="form-item-box-two">
                    <el-form-item label="模型用途" prop="usageType">
                        <el-select v-model="formData.usageType" disabled>
                            <el-option
                                v-for="(value, key) in usageTypeList"
                                :label="value.label"
                                :key="key"
                                :value="key"
                            />
                        </el-select>
                    </el-form-item>
                    <el-form-item label="模型类型" prop="objectType">
                        <el-select v-model="formData.objectType" disabled>
                            <el-option v-for="(value, key) in objectType" :label="value" :key="key" :value="key" />
                        </el-select>
                    </el-form-item>
                    <el-form-item label="模型能力" prop="capabilitiesConfig">
                        <el-select
                            v-model="capabilitiesConfig"
                            @change="capabilitiesConfigChange"
                            multiple
                            collapse-tags
                            collapse-tags-tooltip
                            clearable
                            placeholder="请选择模型能力"
                            :disabled="
                                formData.isComponent ||
                                formData.modifierType === 'EXTENDED' ||
                                isEdit(dialog.detail?.activeState == 'ACTIVATED')
                            "
                        >
                            <el-option
                                v-for="(value, key) in capabilitiesConfigList"
                                :label="key"
                                :key="key"
                                :value="key"
                            />
                        </el-select>
                    </el-form-item>
                    <el-form-item label="全局搜索" prop="searchEnabled">
                        <el-switch v-model="formData.searchEnabled" :disabled="formData.modifierType === 'EXTENDED'" />
                    </el-form-item>
                </div>
                <el-form-item label="描述" prop="description">
                    <el-input
                        v-model="formData.description"
                        maxlength="200"
                        show-word-limit
                        type="textarea"
                        placeholder="请输入描述"
                    />
                </el-form-item>
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button @click="props.close">取消</el-button>
                    <el-button type="primary" @click="submitForm" :loading="loading">确定</el-button>
                </div>
            </template>
        </el-dialog>
    </div>
</template>
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus';
import type { DataModelObjectTreeDo, SysMetadataObject, SysMetadataObjectVo } from '@great/services';
import { modelThingService } from '@great/services';
import { reactive, ref } from 'vue';
import { modifierType, objectType } from '@/utils/constant';
import { useRouter } from 'vue-router';
import { IconSelect } from '@great/components';
import type { PopupBoxProps } from '@great/utils';
import { useRequest } from 'vue-request';

interface IProps extends PopupBoxProps {
    row?: SysMetadataObjectVo;
    getList: () => Promise<void>;
}
const props = defineProps<IProps>();
const router = useRouter();

interface Dialog {
    title: string;
    width: number;
    detail?: SysMetadataObjectVo;
}
const dialog = reactive<Dialog>({
    title: '新建模型',
    width: 900,
    detail: undefined
});

const formData = reactive<SysMetadataObject>({
    objectName: '',
    displayName: '',
    parentObjectName: '',
    showOrder: undefined,
    objectType: 'STANDARD',
    modifierType: 'SINGLE',
    usageType: 'BUSINESS',
    capabilitiesConfig: '',
    searchEnabled: false,
    isComponent: false,
    description: '',
    icon: ''
});
const capabilitiesConfig = ref<Array<string>>([]); // 模型能力选择
const ruleFormRef = ref<FormInstance>();
const ruleForm = reactive<FormRules<SysMetadataObject>>({
    displayName: [{ required: true, message: '请输入模型名称', trigger: ['blur', 'change'] }],
    objectName: [
        { required: true, message: '请输入标识符', trigger: ['blur', 'change'] },
        {
            validator: (rule, value, callback) => {
                // 大写字母开头
                if (!/^[A-Z]/.test(value)) {
                    return callback(new Error('必须以大写字母开头'));
                }
                // 字母数字组合且符合驼峰命名
                if (!/^[A-Z][a-z0-9]+(?:[A-Z][a-z0-9]+)*$/.test(value)) {
                    return callback(new Error('必须是字母数字组合且符合驼峰命名法'));
                }
                callback();
            },
            trigger: ['blur', 'change']
        }
    ],
    parentObjectName: [{ required: true, message: '请选择父模型', trigger: ['blur', 'change'] }],
    modifierType: [{ required: true, message: '请选择模型性质', trigger: ['blur', 'change'] }],
    usageType: [{ required: true, message: '请选择模型用途', trigger: ['blur', 'change'] }],
    objectType: [{ required: true, message: '请选择模型类型', trigger: ['blur', 'change'] }],
    capabilitiesConfig: [{ required: true, message: '请选择模型能力', trigger: ['blur', 'change'] }],
    searchEnabled: [{ required: true, message: '请选择全局搜索', trigger: ['blur', 'change'] }]
});

const parentModelList = ref<Array<DataModelObjectTreeDo>>([]);
const usageTypeList = {
    BUSINESS: {
        label: '业务模型',
        children: [
            {
                label: '产品',
                value: false
            },
            {
                label: '组件',
                value: true
            }
        ]
    }
};
const capabilitiesConfigList = {
    持久化能力: { capacity: 'Persistent Object', config: {} },
    数据权限能力: { capacity: 'Data Permission', config: {} },
    逻辑删除能力: { capacity: 'Logically Deleted', config: {} }
    // 物模型组件能力: { capacity: 'Thing Component', config: {} }
    // '附件能力（文件存储）': { capacity: 'With Attachment Object', config: {} }
};

// 是否为编辑
const isEdit = (par?: boolean): boolean => {
    if (par === undefined) {
        return dialog.title.includes('修改');
    } else {
        return dialog.title.includes('修改') && par;
    }
};

// 模型能力选择
const capabilitiesConfigChange = (value: string[]) => {
    if (value.length > 0) {
        let casualArr: Array<Record<string, unknown>> = [];
        if ((value.includes('逻辑删除能力') || value.includes('数据权限能力')) && !value.includes('持久化能力'))
            value.push('持久化能力');
        value.forEach(item => {
            casualArr.push(capabilitiesConfigList[item]);
        });
        formData.capabilitiesConfig = JSON.stringify(casualArr);
    } else {
        formData.capabilitiesConfig = '';
    }
};

// 模型性质选择
const modifierTypeChange = (value: string) => {
    if (value !== 'EXTENDED') {
        formData.searchEnabled = false;
        formData.parentObjectName = '';
        formData.isComponent = false;
        formData.objectType = 'STANDARD';
        formData.capabilitiesConfig = '';
        reverseDisplay();
    } else {
        getPageObject();
    }
};

// 父模型选择
const parentObjectNameChange = (value: string) => {
    let taget = parentModelList.value.find(item => item.objectName === value);
    if (taget) {
        formData.searchEnabled = taget.searchEnabled;
        formData.isComponent = taget.isComponent;
        formData.objectType = taget.objectType;
        formData.capabilitiesConfig = taget.capabilitiesConfig;
        reverseDisplay();
    }
};

// 特殊值反显处理
const reverseDisplay = () => {
    // 模型能力
    if (formData.capabilitiesConfig) {
        const casualArr = JSON.parse(formData.capabilitiesConfig);
        capabilitiesConfig.value = [];
        Array.isArray(casualArr) &&
            casualArr.forEach(item => {
                const target = Object.keys(capabilitiesConfigList).find(
                    key => capabilitiesConfigList[key].capacity === item.capacity
                );
                if (target) capabilitiesConfig.value.push(target);
            });
    } else {
        capabilitiesConfig.value = [];
    }
};

// 提交接口请求
const { run, loading } = useRequest(
    () => {
        return modelThingService[isEdit() ? 'editModel' : 'createModel'](formData);
    },
    {
        manual: true,
        onSuccess(res) {
            if (isEdit()) {
                ElNotification({
                    title: '修改成功！',
                    type: 'success'
                });
            } else {
                ElMessageBox.confirm('请继续为模型添加属性、事件、行为！', '创建成功', {
                    confirmButtonText: '继续',
                    cancelButtonText: '完成',
                    type: 'success'
                })
                    .then(() => {
                        router.push({
                            name: 'model-business-detail',
                            params: {
                                id: res.data.id
                            }
                        });
                    })
                    .catch(() => {});
            }
            closeDialog();
        }
    }
);
// 表单提交
const submitForm = () => {
    ruleFormRef.value?.validate(valid => {
        valid && run();
    });
};

// 获取父模型
const getPageObject = async () => {
    if (parentModelList.value.length > 0) return;
    const res = await modelThingService.getPageObject({
        current: -1,
        size: 9999999,
        usageType: 'BUSINESS',
        modifierType: 'ABSTRACT'
    });
    parentModelList.value = res.data.records;
};

//关闭弹框
const closeDialog = () => {
    props.close();
    props.getList();
};

// 打开弹框
const openDialog = () => {
    if (props.row) {
        dialog.title = '修改模型';
        dialog.detail = JSON.parse(JSON.stringify(props.row));
        formData.id = props.row.id;
        Object.keys(formData).forEach(key => {
            formData[key] = (props.row as SysMetadataObject)[key];
        });
        reverseDisplay();
        if (formData.modifierType === 'EXTENDED') getPageObject();
    }
};

const init = () => {
    openDialog();
};
init();
</script>
<style scoped lang="scss">
.create-edit-modal-wrapper {
    .el-form {
        .form-item-box-one {
            display: flex;
            justify-content: space-between;
            > div {
                width: calc((100% - 10px) / 2);
            }
        }
        .form-item-box-two {
            overflow: hidden;
            .el-form-item {
                width: calc((100% - 10px) / 2);
                float: left;
            }
            .usage-type-box {
                :deep(.el-form-item__content) {
                    display: flex;
                    justify-content: space-between;
                    > div {
                        width: calc((100% - 10px) / 2);
                    }
                }
            }
        }
    }
}
</style>
